package org.testis.data;

import org.testis.logging.AtofLogLevel;
import org.testis.logging.LogSenderService;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.jms.JmsException;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessagePostProcessor;


/**
 * A singleton class to distribute test result data object to related queues 
 * by using isAsynchCall property of test step data object. 
 * @author nurhat
 */
public class TestStepResultDataObjectDistributor
{

    private static TestStepResultDataObjectDistributor m_dataDistributor;
    private JmsTemplate m_jmsTemplate;


    private TestStepResultDataObjectDistributor()
    {
    }


    /**
     * A static method for creating singleton instance. This method
     * used in  spring framework supported configuration files
     * to create an instance of this class to be used globally.
     * @param m_jmsTemplate defines default destination of message
     * @return
     */
    public static TestStepResultDataObjectDistributor createInstance(
        JmsTemplate jmsTemplate)
    {
        if (m_dataDistributor == null) {
            m_dataDistributor = new TestStepResultDataObjectDistributor();
            m_dataDistributor.m_jmsTemplate = jmsTemplate;
        }

        return m_dataDistributor;
    }


    public static TestStepResultDataObjectDistributor getInstance()
    {
        return m_dataDistributor;
    }


    /**
     * A method for distributing current test step result data object in test step results data queue. This method
     * called automatically from  spring framework supported configuration files
     * to distribute current test step result data object upon async call or sync call. 
     * @param data
     */
    public boolean distributeData(final TestStepResultDataObject data)
    {
        TestStepResultType type= data.getResultType();
       if(type==null)
           type=TestStepResultType.NULL;
        LogSenderService.putMessageOnQueue("TestStepResultDataDistributor",
                                           AtofLogLevel.INFO,
                                           "Recieved test result data object"+ " with result:"+ type.name(),
                                           data.getDataObj().getMessageId());
        Destination dest = null;
        if (!data.getDataObj().isAsynchCall()) {
            LogSenderService.putMessageOnQueue("TestStepResultDataDistributor",
                                               AtofLogLevel.INFO,
                                               "Sending  test step sync result data object"+ " with result:"+ type.name(),
                                               data.getDataObj().getMessageId() );
            dest =
                new ActiveMQQueue("ts_data_sync_response_queue");

        }
        else {
            LogSenderService.putMessageOnQueue("TestStepResultDataDistributor",
                                               AtofLogLevel.INFO,
                                               "Sending  test step async result data object"+ " with result:"+ type.name(),
                                               data.getDataObj().getMessageId() );
            dest =
                new ActiveMQQueue("ts_data_async_response_queue");
        }

        m_jmsTemplate.setDefaultDestination(dest);
        for (int i = 0; i < 3; i++) {
            try
            {
             m_jmsTemplate.convertAndSend(data,
                                       new MessagePostProcessor()
                                       {

                                           public Message postProcessMessage(
                                               Message message)
                                               throws JMSException
                                           {
                                               message.setJMSCorrelationID(
                                                   data.getDataObj().
                                                   getMessageId());
                                               return message;
                                           }

                                       });
                return true;
            } catch (JmsException ex) {
                LogSenderService.putMessageOnQueue(
                    "TestStepResultDataObjectDistributor",
                    AtofLogLevel.ERROR,
                    "Could not distribute test step data object... " +
                    ex.getMessage()+ " Retry index For Queue:" + i ,
                    data.getDataObj().getMessageId());
               try {
                    Thread.sleep(100);
                } catch (InterruptedException exin) {
                }
            }

        }
        return false;
    }
}
